package bgpemulation;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import network.API;
import network.Message;

import org.w3c.dom.Document;

import eventengine.Event;

public class TrustedAS extends AS{
	
	private static final long PROTOCOL_START = 5000;
	private static final long PROTOCOL_FREQ = 5000;
	
	private Map<Integer, BGPRoutingTable> externalTables = new HashMap<Integer, BGPRoutingTable>();
	private BGPGraph registry;
	
	
	public TrustedAS(int tcpServerPort, int udpChannelPort, String ip,
			Document config, String networkLogFile, String applicationLogFile) {
		super(tcpServerPort, udpChannelPort, ip, config, networkLogFile,
				applicationLogFile);
		rebuildRegistry();
	}
	
	@Override
	public void protocolMessage(Message m){
		ProtocolMessage pm = ProtocolMessage.getPayload(m.getPayload());
		externalTables.put(pm.getASN(), pm.getRoutingTable());
		pm.getRoutingTable().print();
		rebuildRegistry();
	}

	private void rebuildRegistry() {
		registry = new BGPGraph(asNumber(), bgpRoutingTable, originatedPrefixes);
		for(int asn : externalTables.keySet()){
			registry.updateGraph(asn, externalTables.get(asn));
		}
	}
	
	@Override
	public void start() {
		startProtocol();
		super.start();
	}

	private void startProtocol() {
		Event e = new Event(PROTOCOL_START, PROTOCOL_FREQ, null){
			@Override
			public void execute(){
				sendRoutingTable();
			}
		};
		schedule(e);
	}

	@Override
	public void stop(){
		rebuildRegistry();
		try{
			BufferedWriter bw = new BufferedWriter(new FileWriter("trustedregistry" + asNumber() + ".txt"));
			registry.printGraphViz(bw);
			bw.close();
		} catch(Exception e){
			e.printStackTrace();
			System.exit(0);
		}
		super.stop();
	}
	
	private void sendRoutingTable(){
		broadcast(protocolNeighbors, ProtocolMessage.buildPayload(asNumber(), bgpRoutingTable), API.TCP, false);
	}
}
